[IA64] changed foreign domain page mapping semantic.
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Tue, 5 Dec 2006 17:59:32 +0000 (10:59 -0700)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Tue, 5 Dec 2006 17:59:32 +0000 (10:59 -0700)
x86 foreign HVM domain page mapping semantic was changed to use gmfn
instead mfn.  It applies to domains with auto_translated_mode enabled,
and all ia64 domains enable auto_translated_mode.  This patch changes
ia64 foreign domain page mapping to use gmfn and fixes ia64 domU buidler.
However this patch breaks domain save/restore/dump-core.
They should also be fixed-up

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
tools/libxc/xc_linux_build.c
xen/arch/ia64/xen/dom0_ops.c
xen/arch/ia64/xen/mm.c
xen/include/asm-ia64/mm.h
xen/include/public/arch-ia64.h

index 98b5982e2a11f9cbbfa5f138d95304fc0cd491a7..9bd507a6bf693b82c6773e2a2cf4d644f9fd3f64 100644 (file)
@@ -497,7 +497,7 @@ xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
                            unsigned long addr,
                            struct xen_ia64_privcmd_range* privcmd_range,
                            int i,
-                           unsigned long mfn,
+                           unsigned long gmfn,
                            pgprot_t prot,
                            domid_t domid)
 {
@@ -506,7 +506,7 @@ xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
        unsigned long gpfn;
        unsigned long flags;
 
-       if ((addr & ~PAGE_MASK) != 0 || mfn == INVALID_MFN) {
+       if ((addr & ~PAGE_MASK) != 0 || gmfn == INVALID_MFN) {
                error = -EINVAL;
                goto out;
        }
@@ -521,7 +521,7 @@ xen_ia64_privcmd_entry_mmap(struct vm_area_struct* vma,
        if (pgprot_val(prot) == PROT_READ) {
                flags = ASSIGN_readonly;
        }
-       error = HYPERVISOR_add_physmap(gpfn, mfn, flags, domid);
+       error = HYPERVISOR_add_physmap_with_gmfn(gpfn, gmfn, flags, domid);
        if (error != 0) {
                goto out;
        }
@@ -732,7 +732,7 @@ out_enomem0:
 int
 direct_remap_pfn_range(struct vm_area_struct *vma,
                       unsigned long address,   // process virtual address
-                      unsigned long mfn,       // mfn, mfn + 1, ... mfn + size/PAGE_SIZE
+                      unsigned long gmfn,      // gmfn, gmfn + 1, ... gmfn + size/PAGE_SIZE
                       unsigned long size,
                       pgprot_t prot,
                       domid_t  domid)          // target domain
@@ -755,13 +755,13 @@ direct_remap_pfn_range(struct vm_area_struct *vma,
 
        i = (address - vma->vm_start) >> PAGE_SHIFT;
        for (offset = 0; offset < size; offset += PAGE_SIZE) {
-               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & PAGE_MASK, privcmd_range, entry_offset + i, mfn, prot, domid);
+               error = xen_ia64_privcmd_entry_mmap(vma, (address + offset) & PAGE_MASK, privcmd_range, entry_offset + i, gmfn, prot, domid);
                if (error != 0) {
                        break;
                }
 
                i++;
-               mfn++;
+               gmfn++;
         }
 
        return error;
index 4b5ea2dae054d59a0dc2f0648c4c0718a4b5e324..19be0e6ed390bc1aa3c1bdc96ff5144e0c69033b 100644 (file)
@@ -387,6 +387,28 @@ HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
        return ret;
 }
 
+static inline unsigned long
+__HYPERVISOR_add_physmap_with_gmfn(unsigned long gpfn, unsigned long gmfn,
+                                   unsigned long flags, domid_t domid)
+{
+       return _hypercall5(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_add_physmap_with_gmfn,
+                          gpfn, gmfn, flags, domid);
+}
+
+static inline unsigned long
+HYPERVISOR_add_physmap_with_gmfn(unsigned long gpfn, unsigned long gmfn,
+                                unsigned long flags, domid_t domid)
+{
+       unsigned long ret = 0;
+       BUG_ON(!is_running_on_xen());//XXX
+       if (is_running_on_xen()) {
+               ret = __HYPERVISOR_add_physmap_with_gmfn(gpfn, gmfn,
+                                                        flags, domid);
+       }
+       return ret;
+}
+
 #ifdef CONFIG_XEN_IA64_EXPOSE_P2M
 static inline unsigned long
 HYPERVISOR_expose_p2m(unsigned long conv_start_gpfn,
index e3f68b6f001658f26bcd6f47e682f8ea17702f6a..dc18e58ab26b7b304b2d35ce58558171f01cd1c9 100644 (file)
@@ -481,7 +481,9 @@ static int setup_guest(int xc_handle,
     start_info_t *start_info;
     unsigned long start_info_mpa;
     struct xen_ia64_boot_param *bp;
+#if 0 // see comment below
     shared_info_t *shared_info;
+#endif
     int i;
     DECLARE_DOMCTL;
     int rc;
@@ -553,8 +555,8 @@ static int setup_guest(int xc_handle,
     (load_funcs.loadimage)(image, image_size, xc_handle, dom,
                            page_array + start_page, &dsi);
 
-    *store_mfn = page_array[nr_pages - 2];
-    *console_mfn = page_array[nr_pages - 1];
+    *store_mfn = page_array[nr_pages - 2]; //XXX
+    *console_mfn = page_array[nr_pages - 1]; //XXX
     IPRINTF("start_info: 0x%lx at 0x%lx, "
            "store_mfn: 0x%lx at 0x%lx, "
            "console_mfn: 0x%lx at 0x%lx\n",
@@ -593,6 +595,14 @@ static int setup_guest(int xc_handle,
     ctxt->user_regs.r28 = start_info_mpa + sizeof (start_info_t);
     munmap(start_info, PAGE_SIZE);
 
+#if 0
+    /*
+     * XXX FIXME:
+     * The follwoing initialization is done by XEN_DOMCTL_arch_setup as
+     * work around.
+     * Should XENMEM_add_to_physmap with XENMAPSPACE_shared_info be used?
+     */
+
     /* shared_info page starts its life empty. */
     shared_info = xc_map_foreign_range(
         xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, shared_info_frame);
@@ -605,7 +615,7 @@ static int setup_guest(int xc_handle,
     shared_info->arch.start_info_pfn = nr_pages - 3;
 
     munmap(shared_info, PAGE_SIZE);
-
+#endif
     free(page_array);
     return 0;
 
index affcafceaaa991ca1e2dbd80b6cdf115d99cc57d..18c2e2f88e17949ea13afb594bf7ae3a1d298bbd 100644 (file)
@@ -125,6 +125,19 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
                     for_each_vcpu (d, v)
                         v->arch.breakimm = d->arch.breakimm;
                 }
+#if 1
+                /*
+                 * XXX FIXME 
+                 * see comment around shared_info in setup_guest() in 
+                 * libxc/xc_linux_build.c
+                 */
+                {
+                    int i;
+                    d->shared_info->arch.start_info_pfn = ds->maxmem >> PAGE_SHIFT;
+                    for_each_cpu(i)
+                        d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
+                }
+#endif
             }
         }
 
@@ -340,6 +353,10 @@ do_dom0vp_op(unsigned long cmd,
         ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
                                  (domid_t)arg3);
         break;
+    case IA64_DOM0VP_add_physmap_with_gmfn:
+        ret = dom0vp_add_physmap_with_gmfn(d, arg0, arg1, (unsigned int)arg2,
+                                           (domid_t)arg3);
+        break;
     case IA64_DOM0VP_expose_p2m:
         ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3);
         break;
index ad26503c3ead5e4f35ad4c4a3f43074543615799..dbf1908c188bfcaad0c68e2231d0df88f6777e55 100644 (file)
@@ -1261,12 +1261,14 @@ dom0vp_zap_physmap(struct domain *d, unsigned long gpfn,
     return 0;
 }
 
-unsigned long
-dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
-                   unsigned long flags, domid_t domid)
+static unsigned long
+__dom0vp_add_physmap(struct domain* d, unsigned long gpfn,
+                     unsigned long mfn_or_gmfn,
+                     unsigned long flags, domid_t domid, int is_gmfn)
 {
-    int error = 0;
+    int error = -EINVAL;
     struct domain* rd;
+    unsigned long mfn;
 
     /* Not allowed by a domain.  */
     if (flags & (ASSIGN_nocache | ASSIGN_pgc_allocated))
@@ -1283,22 +1285,26 @@ dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
             break;
         default:
             gdprintk(XENLOG_INFO, "d 0x%p domid %d "
-                    "pgfn 0x%lx mfn 0x%lx flags 0x%lx domid %d\n",
-                    d, d->domain_id, gpfn, mfn, flags, domid);
+                    "pgfn 0x%lx mfn_or_gmfn 0x%lx flags 0x%lx domid %d\n",
+                    d, d->domain_id, gpfn, mfn_or_gmfn, flags, domid);
             return -ESRCH;
         }
         BUG_ON(rd == NULL);
         get_knownalive_domain(rd);
     }
 
-    if (unlikely(rd == d || !mfn_valid(mfn))) {
-        error = -EINVAL;
+    if (unlikely(rd == d))
         goto out1;
-    }
-    if (unlikely(get_page(mfn_to_page(mfn), rd) == 0)) {
-        error = -EINVAL;
+    if (is_gmfn) {
+        if (domid == DOMID_XEN || domid == DOMID_IO)
+            goto out1;
+        mfn = gmfn_to_mfn(rd, mfn_or_gmfn);
+    } else 
+        mfn = mfn_or_gmfn;
+    if (unlikely(!mfn_valid(mfn) || get_page(mfn_to_page(mfn), rd) == 0))
         goto out1;
-    }
+
+    error = 0;
     BUG_ON(page_get_owner(mfn_to_page(mfn)) == d &&
            get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
     assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, flags);
@@ -1309,6 +1315,21 @@ out1:
     return error;
 }
 
+unsigned long
+dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
+                   unsigned long flags, domid_t domid)
+{
+    return __dom0vp_add_physmap(d, gpfn, mfn, flags, domid, 0);
+}
+
+unsigned long
+dom0vp_add_physmap_with_gmfn(struct domain* d, unsigned long gpfn,
+                             unsigned long gmfn, unsigned long flags,
+                             domid_t domid)
+{
+    return __dom0vp_add_physmap(d, gpfn, gmfn, flags, domid, 1);
+}
+
 #ifdef CONFIG_XEN_IA64_EXPOSE_P2M
 static struct page_info* p2m_pte_zero_page = NULL;
 
index c3f4b2903d811c3a240f05d30690a117c215ae24..a232bd599c3b6d470bfcafefabbb333ad16f7783 100644 (file)
@@ -441,6 +441,7 @@ extern unsigned long ____lookup_domain_mpa(struct domain *d, unsigned long mpadd
 extern unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);
 extern unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order);
 extern unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned long flags, domid_t domid);
+extern unsigned long dom0vp_add_physmap_with_gmfn(struct domain* d, unsigned long gpfn, unsigned long gmfn, unsigned long flags, domid_t domid);
 #ifdef CONFIG_XEN_IA64_EXPOSE_P2M
 extern void expose_p2m_init(void);
 extern unsigned long dom0vp_expose_p2m(struct domain* d, unsigned long conv_start_gpfn, unsigned long assign_start_gpfn, unsigned long expose_size, unsigned long granule_pfn);
index f3b8e423b5161965e8f379c17c8472c2dbe19ab7..d478fb0afa441a4d4a4e63fc13ffbfad3041fa6e 100644 (file)
@@ -386,6 +386,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
 /* xen perfmon */
 #define IA64_DOM0VP_perfmon             8
 
+/* gmfn version of IA64_DOM0VP_add_physmap */
+#define IA64_DOM0VP_add_physmap_with_gmfn       9
+
 // flags for page assignement to pseudo physical address space
 #define _ASSIGN_readonly                0
 #define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)